/**
 * Copyright (C) 2012 The SkyTvOS Project
 * <p/>
 * Version     Date           Author
 * ─────────────────────────────────────
 * 2014年12月20日         Root.Lu
 */

package com.coocaa.launcher.framework.launcherhost;

import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.view.KeyEvent;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.widget.ViewFlipper;

import com.coocaa.launcher.framework.launcherhost.LauncherHostViewBoundaryEvent.IHostViewBoundaryEventHandler;
import com.coocaa.launcher.framework.launcherhost.LauncherHostViewBoundaryEvent.IHostViewBoundaryEventListener;
import com.coocaa.launcher.framework.launcherhost.LauncherHostViewController.ILauncherHostViewControllerListener;
import com.coocaa.launcher.framework.launcherhost.statusbar.StatusBarHostView;
import com.coocaa.launcher.framework.launcherhost.statusbar.StatusBarHostViewController;
import com.coocaa.launcher.pattern.normal.guide.GuideView;
import com.coocaa.launcher.pattern.normal.guide.GuideView.GuideViewManager;
import com.coocaa.launcher.wallpaper.WallpaperManager;
import com.coocaa.x.framework.utils.Cache;
import com.coocaa.x.framework.utils.LogUtils;
import com.coocaa.x.service.litecontent.api.ContentApi;
import com.coocaa.x.service.litecontent.data.store.com_coocaa_theme.RP_WallpaperList;
import com.coocaa.x.uipackage.BaseView;
import com.tianci.appstore.R;

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

/**
 * TODO 提供统一的主页显示页面的管理容器，负责各页面的显示、切换、刷新
 *
 * @author lu
 * @version 2014年12月23日
 * @see
 */
public class LauncherHostView extends BaseView implements IHostViewBoundaryEventHandler,
        ILauncherHostViewControllerListener, WallpaperManager.OnBackgroundChangeListener {

    public interface ILauncherHostViewListener {
        void onCreate(LauncherHostView hostview);

        void onDestroy(LauncherHostView hostview);
    }

    /**
     * TODO
     * <p>
     * <strong>launcher上具体要显示的页面抽象view</strong>
     * </p>
     * <p>
     * 由具体的launcher显示页来实现view的绘制，但每一个View需要有唯一的name，每一个View的对象需要有唯一的ID，
     * </p>
     * <p>
     * 这些参数需要提供给LauncherHostView来对各个pageview进行管理。
     * </p>
     * <p>
     * <br />
     * </p>
     * <p>
     * <br />
     * </p>
     *
     * @author lu
     * @version 2014年12月23日
     * @see com.coocaa.launcher.framework.launcherhost.LauncherHostView
     */
    public static abstract class LauncherHostPageView extends BaseView {
        private String name = null;
        private boolean bDefault = false, bStatusBarEnabled = true;
        private final String ID = this.toString();

        public LauncherHostPageView(String name, Context context) {
            super(context);
            // TODO Auto-generated constructor stub
            this.name = name;
            mContext = context;
        }

        public String getViewID() {
            return ID;
        }

        public final String getName() {
            return name;
        }

        /**
         * TODO 设置是否为默认页，如果某一个pageview设置为default==true，则hostview中会默认显示此pageview，
         * 但每一个hostviewcontroller提供的pageview中只能存在一个pageview设置为default
         *
         * @param value
         * @return void 对方法返回值的说明
         * @throws RuntimeException 对方法中某参数的说明
         * @author lu
         * @version 2014年12月23日 以修改时间为准
         * @see com.coocaa.launcher.framework.launcherhost.LauncherHostViewController
         */
        public final void setDefault(boolean value) throws RuntimeException {
            bDefault = value;
        }

        public final boolean isDefault() {
            return bDefault;
        }

        public final void enableStatusBar(boolean val) {
            bStatusBarEnabled = val;
        }

        public final boolean isStatusBarEnabled() {
            return bStatusBarEnabled;
        }

        public abstract void resetFocus();
    }

    private static LauncherHostView instance = null;

    public synchronized static void init(Context context, ILauncherHostViewListener listener) {
        if (instance == null) {
            instance = new LauncherHostView(context, listener);
            StatusBarHostViewController.init(context);
            LauncherHostViewController.setContext(context);
        }
    }

    public synchronized static void uninit() {
        StatusBarHostViewController.uninit();
        instance = null;
    }

    public static LauncherHostView getInstance() {
        return instance;
    }

    private LauncherHostViewController controller = null;
    private LauncherHostPageView currentview = null;
    private Cache<String, LauncherHostPageView> hostPageViews = new Cache<String, LauncherHostPageView>();
    private ILauncherHostViewListener listener = null;
    private boolean bCreate = false, bDestroy = false;
    private StatusBarHostView statusBar = null;
    private WallPaper wallPaper = null;
    private ViewFlipper viewFlipper = null;
    private GuideView guideView = null;
    private boolean prevStatusBarEnableState = true;

    private LauncherHostView(Context context, ILauncherHostViewListener listener) {
        super(context);
        // TODO Auto-generated constructor stub
        this.listener = listener;
        viewFlipper = new ViewFlipper(context) {
            @Override
            protected void onDetachedFromWindow() {
                try {
                    super.onDetachedFromWindow();
                } catch (IllegalArgumentException e) {
                    stopFlipping();
                    e.printStackTrace();
                }
            }
        };
        viewFlipper.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
                LayoutParams.MATCH_PARENT));
        wallPaper = new WallPaper(context);
        guideView = new GuideView(context);
        addView(wallPaper);
        addView(viewFlipper);
        // addView(guideView);
        setBackgroundColor(Color.BLACK);

        GuideViewManager.getInstance().setGuideView(guideView, guideView);
        GuideViewManager.getInstance().hideMe();
    }

    /**
     * TODO 设置当前的hostviewcontroller，通过不同的hostviewcontroller可以实现不同的首页布局、功能
     *
     * @param controller 某一具体的LauncherHostViewController
     * @return void
     * @author lu
     * @version 2014年12月23日 以修改时间为准
     * @see com.coocaa.launcher.framework.launcherhost.LauncherHostViewController
     */
    public void create(LauncherHostViewController controller) {
        if (this.controller != null)
            return;
        this.controller = controller;
        this.controller.setListener(this);
        this.controller.setBoundaryEventHandler(this);
        this.controller.create();
    }

    public void destroy() {
        if (this.controller == null)
            return;
        this.controller.destroy();
    }

    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (this.controller != null)
            return this.controller.onKeyDown(keyCode, event);
        return false;
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        this.controller.onActivityResult(requestCode, resultCode, data);
    }

    private boolean isHandlingBoundaryEvent = false;
    private Timer boundaryEventTimer = null;

    @Override
    public synchronized void onHostViewBoundaryEvent(final LauncherHostViewBoundaryEvent event,
                                                     final IHostViewBoundaryEventListener listener) {
        synchronized (this) {
            if (isHandlingBoundaryEvent || event == null) {
                listener.onHostViewBoundaryEventCompleteFailed(event);
                if (boundaryEventTimer == null) {
                    boundaryEventTimer = new Timer();
                    boundaryEventTimer.schedule(new TimerTask() {
                        @Override
                        public void run() {
                            synchronized (LauncherHostView.this) {
                                boundaryEventTimer = null;
                                isHandlingBoundaryEvent = false;
                            }
                        }
                    }, 2000);
                }
                return;
            }
            isHandlingBoundaryEvent = true;
            if (boundaryEventTimer == null) {
                boundaryEventTimer = new Timer();
                boundaryEventTimer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        synchronized (LauncherHostView.this) {
                            boundaryEventTimer = null;
                            isHandlingBoundaryEvent = false;
                        }
                    }
                }, 2000);
            }
        }
        String id = event.getToLauncherHostPageView().getViewID();
        final Animation in = event.getInAnimation();
        final Animation out = event.getOutAnimation();
        final LauncherHostPageView view = event.getToLauncherHostPageView();
        LogUtils.d("switch", "--------flipper processing");
        if (currentview == null) {
            LogUtils.d("switch", "         currentView == null!!!!!!!!!!!!!!");
        }
        if (!hostPageViews.containsKey(id)) {
            LogUtils.d("switch", "         hostPageView !contain id, id = +" + id
                    + " !!!!!!!!!!!!!!");
        }
        if (hostPageViews.containsKey(id) && currentview != null) {
            LogUtils.d("switch", "         ready to switch");
            runOnUiThread(new Runnable() {
                private void handleFinish(boolean success) {
                    try {
                        if (success)
                            listener.onHostViewBoundaryEventComplete(event);
                        else
                            listener.onHostViewBoundaryEventCompleteFailed(event);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    synchronized (LauncherHostView.this) {
                        if (boundaryEventTimer != null) {
                            boundaryEventTimer.cancel();
                            boundaryEventTimer = null;
                        }
                        isHandlingBoundaryEvent = false;
                    }
                }

                private int getTarget() {
                    int target = -1;
                    int size = viewFlipper.getChildCount();
                    for (int i = 0; i < size; i++) {
                        if (viewFlipper.getChildAt(i) == view) {
                            target = i;
                            break;
                        }
                    }
                    return target;
                }

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    int target = getTarget();
                    if (target == -1) {
                        handleFinish(false);
                        return;
                    }
                    if (in != null || out != null) {
                        final Animation myAnimation = (in != null) ? in : out;
                        myAnimation.setAnimationListener(new AnimationListener() {

                            @Override
                            public void onAnimationStart(Animation animation) {
                                // TODO Auto-generated method stub
                            }

                            @Override
                            public void onAnimationRepeat(Animation animation) {
                                // TODO Auto-generated method stub

                            }

                            @Override
                            public void onAnimationEnd(Animation animation) {
                                // TODO Auto-generated method stub
                                viewFlipper.setInAnimation(null);
                                viewFlipper.setOutAnimation(null);
                                myAnimation.setAnimationListener(null);
                                currentview = view;
                                handleFinish(true);
                            }
                        });
                        viewFlipper.setInAnimation(in);
                        viewFlipper.setOutAnimation(out);
                        viewFlipper.setDisplayedChild(target);
                        if (prevStatusBarEnableState != view.isStatusBarEnabled()) {
                            prevStatusBarEnableState = view.isStatusBarEnabled();
                            if (!view.isStatusBarEnabled())
                                statusBar.hide();
                            else
                                statusBar.show();
                        } else
                            handleFinish(true);
                    } else {
                        viewFlipper.setDisplayedChild(target);
                        currentview = view;
                        if (prevStatusBarEnableState != view.isStatusBarEnabled()) {
                            prevStatusBarEnableState = view.isStatusBarEnabled();
                            if (!view.isStatusBarEnabled())
                                statusBar.hide();
                            else
                                statusBar.show();
                        }
                        handleFinish(true);
                    }
                }
            });
        } else {
            LogUtils.d("switch", "--------will not switch!!!!!!!!!!!!!!!!!!!!!");
            listener.onHostViewBoundaryEventCompleteFailed(event);
            synchronized (LauncherHostView.this) {
                if (boundaryEventTimer != null) {
                    boundaryEventTimer.cancel();
                    boundaryEventTimer = null;
                }
                isHandlingBoundaryEvent = false;
            }
        }
    }

    @Override
    public void onCreate(LauncherHostViewController controller,
                         final List<LauncherHostPageView> views) {
        // TODO Auto-generated method stub
        synchronized (this) {
            bDestroy = false;
        }
        WallpaperManager.getInstance().addBackgroundChangeListener(this);
        new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    RP_WallpaperList.WallPaper_Item current = ContentApi.getCurrentWallpaper();
                    if (current != null) {
                        wallPaper.setWallpaperItem(current);
                        WallpaperManager.getInstance().setCurrent(current);
                    } else {
                        RP_WallpaperList.WallPaper_Item item = new RP_WallpaperList.WallPaper_Item();
                        item.smallUrl = "res://" + mContext.getPackageName() + "/" + R.drawable.bg_1;
                        item.bigUrl = item.smallUrl;
                        wallPaper.setWallpaperItem(item);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
        currentview = null;
        hostPageViews.clear();
        mCreated = true;
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                if (statusBar != null)
                    removeView(statusBar);
                viewFlipper.removeAllViews();

                if (views != null && views.size() > 0) {
                    int target = 0;
                    for (int i = 0; i < views.size(); i++) {
                        LauncherHostPageView v = views.get(i);
                        if (v.isDefault() && currentview == null) {
                            currentview = v;
                            target = i;
                        }
                        hostPageViews.add(v.getViewID(), v);
                        viewFlipper.addView(v);
                    }
                    if (currentview == null) {
                        LogUtils.e("The hostviewcontroller has no default pageview so use the first one instead!");
                        currentview = views.get(0);
                        prevStatusBarEnableState = currentview.isStatusBarEnabled();
                    }
                    viewFlipper.setDisplayedChild(target);
                    currentview.resetFocus();
                }

                statusBar = StatusBarHostViewController.getInstance().getStatusBarHostView();
                if (statusBar != null) {
                    statusBar.config();
                    addView(statusBar);
                    statusBar.show();
                }
                currentview.show();
                synchronized (LauncherHostView.this) {
                    bCreate = true;
                    LauncherHostView.this.notify();
                }
            }
        });
        synchronized (this) {
            if (!bCreate)
                try {
                    wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        }
        if (listener != null)
            listener.onCreate(this);
    }

    @Override
    public void onDestroy(LauncherHostViewController controller) {
        // TODO Auto-generated method stub
        synchronized (this) {
            bCreate = false;
        }
        hostPageViews.clear();
        WallpaperManager.getInstance().removeBackgroundChangeListener(this);
        if (statusBar != null) {
            statusBar.clearConfig();
        }
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                viewFlipper.removeAllViews();
                synchronized (LauncherHostView.this) {
                    bDestroy = true;
                    LauncherHostView.this.notify();
                }
            }
        });
        synchronized (this) {
            if (!bDestroy)
                try {
                    wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        }
        wallPaper = null;
        if (listener != null)
            listener.onDestroy(this);
        this.controller = null;
    }

    private boolean mCreated = false;

    @Override
    public void onPageViewAdded(LauncherHostViewController controller,
                                final LauncherHostPageView view) {
        // TODO Auto-generated method stub
        while (!mCreated)
            ;
        final String id = view.getViewID();
        LogUtils.d("lll", "keys:" + hostPageViews.keys() + "   id=" + id + "  val:" + hostPageViews.containsKey(id));
        if (!hostPageViews.containsKey(id)) {
            hostPageViews.add(id, view);
            LogUtils.d("lll", "hostPageViews addview!!! id:" + id);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    viewFlipper.addView(view);
                    LogUtils.d("lll", "viewFlipper addview!!! id:" + id);
                }
            });
        }
    }

    @Override
    public void onPageViewRemoved(LauncherHostViewController controller,
                                  final LauncherHostPageView view) {
        // TODO Auto-generated method stub
        String id = view.getViewID();
        LogUtils.d("lll", "onPageViewRemoved view id:" + id + "   hostPageViews.containsKe:" + hostPageViews.containsKey(id));
        if (hostPageViews.containsKey(id)) {
            hostPageViews.remove(id);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    viewFlipper.removeView(view);
                }
            });
        }
    }

    @Override
    public void onBackgroundChange() {
        // TODO Auto-generated method stub
        beginChangeBackground();
    }
    private void beginChangeBackground(){
        AlphaAnimation animation = new AlphaAnimation(1.0f,0f);
        animation.setDuration(2000);
        animation.setAnimationListener(new AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {

            }

            @Override
            public void onAnimationRepeat(Animation animation) {
                RP_WallpaperList.WallPaper_Item current = WallpaperManager.getInstance().getCurrent();
                if (current != null) {
                    LogUtils.d("wallpaper", "change wallpaper " + current.bigUrl);
                    wallPaper.setWallpaperItem(current);
                } else {
                    RP_WallpaperList.WallPaper_Item item = new RP_WallpaperList.WallPaper_Item();
                    item.smallUrl = "res://" + mContext.getPackageName() + "/" + R.drawable.bg_1;
                    item.bigUrl = item.smallUrl;
                    wallPaper.setWallpaperItem(item);
                }
            }
        });
        animation.setRepeatCount(1);
        animation.setRepeatMode(Animation.REVERSE);
        wallPaper.startAnimation(animation);
    }
}
